package ui.cli.console;

import common.Commands;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.PrintStream;

import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import ui.gui.documents.toolbox.AbstractToolbox;

/**
 *
 * @author stephane
 */
public class Console extends AbstractToolbox implements KeyListener, FocusListener {

    private static final long serialVersionUID = 1L;
    private static Console _instance = null;

    public static Console getInstance() {
        if (_instance == null) {
            _instance = new Console();
        }
        return _instance;
    }

    protected Console() {
        initComponent();
    }
    private JTextPane _area = null;
    private JScrollPane _scroll = null;
    private PrintStreamConsole _console = null;
    private Style _styleBase = null;
    private Style _clacOutputStyle = null;
    private PrintStream _originalStream = null;
    
    public void restoreOriginalOutputStream() {
    	System.setOut(_originalStream);
    }
    public void restoreEmbeddedConsole() {
    	System.setOut(this._console);
    }
    
    private void initComponent() {
        setTitle("Console");
        this._area = new JTextPane();
        this._scroll = new JScrollPane(this._area);
        this._area.setFont(new Font("Courier New", Font.PLAIN, 11));
        this._area.getCaret().setVisible(true);
        this.setLayout(new BorderLayout());
        this.add(this._scroll, BorderLayout.CENTER);
        this._area.setEditable(false);
        
        this._area.addFocusListener(this);
        this._console = new PrintStreamConsole(System.out);
        this._area.addKeyListener(this);
        this._originalStream = System.out;
        System.setOut(this._console);
        this._console.setArea(_area);
        _area.setText("");
        InitStyle();
     
        
    }

    private void InitStyle() {
        _styleBase = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);
        _clacOutputStyle = _area.getStyledDocument().addStyle("clacOutput", _styleBase);
        StyleConstants.setForeground(_clacOutputStyle, Color.GRAY);
        StyleConstants.setItalic(_clacOutputStyle, true);
        
    }
    public void sendOutput(String line) {
    	try
    	{
    	this._area.getStyledDocument().insertString(this._area.getStyledDocument().getLength(), line, _styleBase);
    	}
    	catch (Exception ex) {
    		
    	}
    }
    private String _currentLine = "";

    @Override
    public void keyTyped(KeyEvent e) {
        try {
            if (!e.isActionKey() && e.getKeyChar() != '\n') {
                if (e.getKeyChar() != '\b') {
                    _currentLine += String.valueOf(e.getKeyChar());
                    this._area.getStyledDocument().insertString(this._area.getStyledDocument().getLength(), String.valueOf(e.getKeyChar()), _styleBase);

                } else {
                    if (_currentLine.length() > 0) {
                        
                       this._area.getStyledDocument().remove(this._area.getStyledDocument().getLength() - 1, 1);
                       _currentLine = _currentLine.substring(0,_currentLine.length()-1);
                    }
                }
            } else if (e.getKeyChar() == '\n') {

                Commands.RunCommand(_currentLine, false);
                _currentLine = "";

            }
            this._area.setSelectionStart(this._area.getText().length());
            this._area.getCaret().setVisible(true);
        } catch (BadLocationException ex) {
            System.out.println(ex);
        }
    }

    @Override
    public void keyPressed(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    @Override
    public void focusGained(FocusEvent e) {
        this._console.setArea(_area);
        this._area.getCaret().setVisible(true);
    }

    @Override
    public void focusLost(FocusEvent e) {
        
    }
}
